package com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend;

import java.awt.image.BufferedImage;

import com.nulldev.util.concurrency.threadIt.v4.emapi.cntft.ControllableFutureTask;
import com.nulldev.util.data.Images.ImageUtil;
import com.nulldev.util.data.Images.legacy.TextObf;
import com.nulldev.util.data.Images.legacy.TextObf.ObfuscationMethod;
import com.nulldev.util.data.Sets.DataSet;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.web.HttpServer3.Response;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.nCaptcha;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend.user.User;
import com.nulldev.util.web.HttpServer3.extensions.nCaptcha.backend.util.UUIDCookieLoader;
import com.nulldev.util.web.HttpServer3.pages.v3.ASyncHttpPage3;

public class RequestCaptcha extends ASyncHttpPage3 {

	private static final String JSON_MIME = "application/json; charset=utf-8";
	private static final String JSON_MISSING_COOKIE_ERROR = UniJsonValue.object(2).add("error", true).add("reason", "NCAPTCHA_MISSING_COOKIE").toString();

	public RequestCaptcha() {
		super("/captcha/generate_captcha", true);
		super.setCachingMethod(CachingMethod.NO_CACHE);
	}

	private final static BufferedImage adone = TextObf.obfuscate("Captcha already done.", ObfuscationMethod.None, TextObf.__font(Captcha.BASE_TEXT_SIZE));
	private final static String adone_b64 = ImageUtil.convertImageDataBase64(adone);

	private final static BufferedImage failed = TextObf.obfuscate("You seem to be a robot, please try again later.", ObfuscationMethod.None,
			TextObf.__font(Captcha.LARGE_BASE_TEXT_SIZE));
	private final static String failed_b64 = ImageUtil.convertImageDataBase64(failed);

	@SuppressWarnings("resource")
	@Override
	public void onFutureRequest(final Request request, final ControllableFutureTask<Response> r) {
		final User user = UUIDCookieLoader.userFromRequest(request);
		if (user == null) {
			r.complete(new Response(200, createStream(JSON_MISSING_COOKIE_ERROR)).setCustomMime(JSON_MIME));
			return;
		}

		final UniJsonValue object = UniJsonValue.object(3);

		object.add("uuid", user.uuid());
		if (user.captchaDone()) {
			object.add("type", "type:captcha_done");
			object.add("image", "data:image/png;base64," + adone_b64);
			r.complete(new Response(200, object, object).setCustomMime(JSON_MIME));
			return;
		}
		if (user.isNotBot()) {
			final Captcha c = nCaptcha.randomCaptcha(user);
			final DataSet<String, String[]> b64 = c.generateBase64Image(user.getLevel(), request);
			user.setExpectedResults(b64.getB());
			object.add("type", "type:" + c.getType());
			object.add("image", b64.getA());
			r.complete(new Response(200, object, object).setCustomMime(JSON_MIME));
			return;
		} else {
			object.add("type", "type:bot_detected");
			object.add("image", "data:image/png;base64," + failed_b64);
			r.complete(new Response(406, object, object).setCustomMime(JSON_MIME));
			return;
		}
	}

}
